package com.cheetah.start.common.shoesImg;

import org.opencv.core.*;
import org.opencv.features2d.DescriptorMatcher;
import org.opencv.features2d.Feature2D;
import org.opencv.features2d.ORB;
import org.opencv.features2d.SIFT;

import java.util.List;

public class FeatureBasedComparison {

    /**
     * 使用特征点匹配，自动忽略背景
     */
    public static double compareByFeatureMatching(Mat image1, Mat image2) {
        // 创建特征检测器
        Feature2D orb = ORB.create(1000);

        // 检测关键点和计算描述符
        MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
        MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
        Mat descriptors1 = new Mat();
        Mat descriptors2 = new Mat();

        orb.detectAndCompute(image1, new Mat(), keypoints1, descriptors1);
        orb.detectAndCompute(image2, new Mat(), keypoints2, descriptors2);

        // 如果特征点太少，返回低相似度
        if (descriptors1.rows() < 10 || descriptors2.rows() < 10) {
            return 0.0;
        }

        // 特征匹配
        DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
        MatOfDMatch matches = new MatOfDMatch();
        matcher.match(descriptors1, descriptors2, matches);

        // 计算匹配距离
        List<DMatch> matchList = matches.toList();
        double totalDistance = 0;
        for (DMatch match : matchList) {
            totalDistance += match.distance;
        }

        double averageDistance = totalDistance / matchList.size();

        // 转换为相似度分数（距离越小，相似度越高）
        double similarity = Math.max(0, 1 - averageDistance / 100);

        return similarity;
    }

    /**
     * 改进的特征匹配 - 只匹配显著区域
     */
    public static double compareBySalientFeatures(Mat image1, Mat image2) {
        // 先提取前景
        Mat foreground1 = UniversalBackgroundRemoval.removeAnyBackground(image1);
        Mat foreground2 = UniversalBackgroundRemoval.removeAnyBackground(image2);

        // 然后在前景区域检测特征
        Feature2D sift = SIFT.create(500);

        MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
        MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
        Mat descriptors1 = new Mat();
        Mat descriptors2 = new Mat();

        // 创建前景掩码
        Mat mask1 = createForegroundMask(foreground1);
        Mat mask2 = createForegroundMask(foreground2);

        sift.detectAndCompute(image1, mask1, keypoints1, descriptors1);
        sift.detectAndCompute(image2, mask2, keypoints2, descriptors2);

        if (descriptors1.rows() < 5 || descriptors2.rows() < 5) {
            return 0.0;
        }

        // 使用FLANN匹配器
        DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
        MatOfDMatch matches = new MatOfDMatch();
        matcher.match(descriptors1, descriptors2, matches);

        // 筛选好的匹配
        List<DMatch> matchList = matches.toList();
        matchList.sort((a, b) -> Float.compare(a.distance, b.distance));

        // 取前50%的匹配
        int goodMatchesCount = (int) (matchList.size() * 0.5);
        double goodDistanceSum = 0;
        for (int i = 0; i < goodMatchesCount && i < matchList.size(); i++) {
            goodDistanceSum += matchList.get(i).distance;
        }

        double avgGoodDistance = goodDistanceSum / goodMatchesCount;
        double similarity = Math.max(0, 1 - avgGoodDistance / 200);

        return similarity;
    }

    private static Mat createForegroundMask(Mat image) {
        Mat mask = new Mat();
        Core.inRange(image, new Scalar(1, 1, 1), new Scalar(255, 255, 255), mask);
        return mask;
    }
}
